﻿/** 
 * The Scene */
 
 import SCUMMCore.*;
 import SCUMMCore.Nodes.*;
 import SCUMMCharacter.*;
 import SCUMMGameControl.*;
 
class SCUMMScenario.SCUMMScene extends SCUMMObject {
	
	/** Fields **/
	private var oGame:SCUMMGame;
	private var bCanWalk:Boolean;
	private var oGraph:NodeCollection;
	private var mcWalkableArea:MovieClip;
	private var btnClickableArea:Button;
	private var aListEvent:Array;
	private var oCurrentEvent:Event;
	private var oMainActor:SCUMMActor;
	private var oActorCamera:SCUMMActor;
	private var oActionsBar:SCUMMActionBar;
	
	/** Property **/
	public function get listEvent():Array {
		return this.aListEvent;
	}
	
	public function get walkableArea():MovieClip {
		return this.mcWalkableArea;
	}
	public function set walkableArea( value:MovieClip ):Void {
		this.mcWalkableArea = walkableArea;
	}

	public function get clickableArea():Button {
		return this.btnClickableArea;
	}
	public function set clickableArea( value:Button ):Void {
		this.btnClickableArea = value;
	}
	
	public function get currentEvent():Event {
		return this.oCurrentEvent;
	}
	
	public function get game():SCUMMGame {
		return this.oGame;
	}
	
	public function get canWalk():Boolean {
		return this.bCanWalk;
	}
	public function set canWalk( value:Boolean ):Void {
		this.bCanWalk = value;
	}
	
	public function set mainActor( value:SCUMMActor ):Void {
		this.oMainActor = value;
	}
	public function get mainActor():SCUMMActor  {
		return this.oMainActor;
	}

	public function set actorCamera( value:SCUMMActor ):Void {
		this.oActorCamera = value;
	}
	public function get actorCamera():SCUMMActor  {
		return this.oActorCamera;
	}
		
	/** Methods **/
	public function SCUMMScene( poGame:SCUMMGame, pmcScenario:MovieClip) {
		if ( pmcScenario.WalkableArea == undefined) {
			throw new Error("SCUMMScene - Error: Walkable area can't be null");
		}
		if ( pmcScenario.ClickableArea == undefined )
			throw new Error("SCUMMScene - Error: Clickable area can't be null");
		
		if ( poGame == null )
			throw new Error("SCUMMScene - Error: Clickable area can't be null");
		
		this.bCanWalk = true;
		this.oGame = poGame;
		this.mcSprite = pmcScenario;
		this.mcWalkableArea = pmcScenario.WalkableArea;
		this.btnClickableArea = pmcScenario.ClickableArea;
		this.oGraph = new NodeCollection();
		this.aListEvent = new Array();
		this.addNodeColection();
				
		var oScene:SCUMMScene = this;
 		//This is the main loop implementation. In every frame, the "centerView" method is called.
 		this.mcSprite.onEnterFrame = function() {
 			oScene.centerView();
 		};
 		//Code for handle the click actions in the game(by catrina)
 		this.btnClickableArea.useHandCursor = false;
 		this.btnClickableArea.onRelease = function() {
 			if ( oScene.listEvent.length > 0 ) {
 				oScene.currentEvent.finishEvent();
 			}
			else if ( oScene.canWalk ) {
				oScene.oMainActor.walkTo(
					oScene.mc._xmouse,
					oScene.mc._ymouse
				);
			}
		};
		
		
	}
	
	public function crateMainActor( pmcSprite:MovieClip ):SCUMMActor {
  		if( pmcSprite == undefined )
			throw new Error("SCUMMScene - Error: The sprite of the main actor can't be null");
 		this.oMainActor = new SCUMMActor(pmcSprite, this);
 		this.oActorCamera = this.oMainActor;
 		return this.oMainActor;
 	}
	
	// Temporário
	private function addNodeColection()
	{
		var aNodes:Array = new Array();
		
		for ( var x:String in this.mcSprite )
			if ( x.substr(0, 7) == "myNodo_" )
				aNodes.push(x);
		aNodes.sort();
		
		var oNode:Node;
		
		for ( var i = 0; i < aNodes.length; i++ ) {
			oNode = new Node(this.mcSprite[aNodes[i]]);
			if ( i != 0 )
				oNode.addChild(i - 1);
			if ( i != (aNodes.length - 1) )
				oNode.addChild(i + 1);
			this.oGraph.addNode(oNode);
		}
	}
	
	public function findPath(init_x:Number, init_y:Number, end_x:Number, end_y:Number):NodeCollection {
		var myNode:Node = new Node();
		myNode._x = init_x;
		myNode._y = init_y;
		var NodoInicio:Node = this.oGraph.getCloserNode(myNode);
		myNode._x = end_x;
		myNode._y = end_y;
		var NodoFin:Node = this.oGraph.getCloserNode(myNode);
		return this.oGraph.findPath(NodoInicio, NodoFin);
	}
	//Add a walk to the actions queue. usefull for creating animations.
	public function addWalk( actor:SCUMMActor, x:Number, y:Number ):Void {
		var oEvento:Event = Event.actorWalkTo(actor, x, y);
		this.aListEvent.push(oEvento);
		if ( this.aListEvent.length == 1 )
			oEvento.run();
	}
	//Add a speak to the actions queue. usefull for creating animations.	
	public function addSpeak( actor:SCUMMActor, text:Array ):Void {
		var oEvento:Event = Event.actorSpeak(text, actor);
		this.aListEvent.push(oEvento);
		
		if ( this.aListEvent.length == 1 ) {
			this.oCurrentEvent = oEvento;
			oEvento.run();
		}
	}
	
	public function addAnimation( sprite:MovieClip ):Void {
		var oEvento:Event = Event.amination(sprite, this);
		this.aListEvent.push(oEvento);
		if ( this.aListEvent.length == 1 ) {
			this.oCurrentEvent = oEvento;
			this.oCurrentEvent.run();
		}
	}
	
	public function endEvent():Void {

		this.aListEvent.shift();
		if ( this.aListEvent.length > 0 ) {
			this.oCurrentEvent = Event(this.aListEvent[0]);
			this.oCurrentEvent.run();
		}
	}
	//This function follow the actor for the scene.
	public function centerView():Void {
		var actorPoint:Object = {
			x:this.oActorCamera.mc._x,
			y:this.oActorCamera.mc._y
		};
		this.mcSprite.localToGlobal(actorPoint);
		
		
		// center view
		if ( actorPoint.x >= Stage.width/2 ) {
			if ( (this.mcSprite._width - Math.abs(this.mcSprite._x) - Stage.width) >= (actorPoint.x - Stage.width/2) ) {
				this.mcSprite._x -= actorPoint.x - Stage.width/2;
			}
			else {
				this.mcSprite._x =  Stage.width - this.mcSprite._width;
			}
		}
		else {
			if ( this.mcSprite._x < (actorPoint.x - Stage.width/2) ) {
				this.mcSprite._x -= actorPoint.x - Stage.width/2;
			}
			else {
				this.mcSprite._x = 0;
			}
		}
	}
}